﻿using D.IdentityDbStore.DbContext;
using D.IdentityDbStore.Entities;
using D.IdentityDbStore.Mappers;
using IdentityServer4.Stores;
using SqlSugar;

namespace D.IdentityDbStore.Stores
{

    /// <summary>
    /// 重写授权信息存储
    /// </summary>
    public class PersistedGrantStore : IPersistedGrantStore
    {
        private readonly ISqlSugarClient _db;
        public PersistedGrantStore(DbSql dbSql)
        {
            _db = dbSql.Db;
        }

        /// <summary>
        /// 根据用户标识获取所有的授权信息
        /// </summary>
        /// <param name="subjectId">用户标识</param>
        /// <returns></returns>
        public async Task<IEnumerable<IdentityServer4.Models.PersistedGrant>> GetAllAsync(PersistedGrantFilter filter)
        {
            //"select * from PersistedGrants where SubjectId=@subjectId";
            var list = await _db.Queryable<PersistedGrant>()
               .Where(x => x.SubjectId == filter.SubjectId)
               .Where(x => x.SessionId == filter.SessionId)
               .Where(x => x.ClientId == filter.ClientId)
               .Where(x => x.Type == filter.Type)
               .Select<PersistedGrant>()
               .ToListAsync(m=>m.ToModel());
            return list;
        }

        /// <summary>
        /// 根据key获取授权信息
        /// </summary>
        /// <param name="key">认证信息</param>
        /// <returns></returns>
        public async Task<IdentityServer4.Models.PersistedGrant> GetAsync(string key)
        {
            //select * from PersistedGrants where [Key]=@key
            var mod = await _db.Queryable<PersistedGrant>().Where(x => x.Key == key).Select<PersistedGrant>().FirstAsync();
            
            return mod.ToModel();
        }

        /// <summary>
        /// 根据用户标识和客户端ID移除所有的授权信息
        /// </summary>
        /// <param name="subjectId">用户标识</param>
        /// <param name="clientId">客户端ID</param>
        /// <returns></returns>
        public async Task RemoveAllAsync(string subjectId, string clientId)
        {
            //delete from PersistedGrants where ClientId=@clientId and SubjectId=@subjectId";
            await _db.Deleteable<PersistedGrant>()
                      .Where(m => m.ClientId == clientId && m.SubjectId == subjectId)
                      .ExecuteCommandAsync();
        }

        /// <summary>
        /// 移除指定的标识、客户端、类型等授权信息
        /// </summary>
        /// <param name="subjectId">用户标识</param>
        /// <param name="clientId">客户端ID</param>
        /// <param name="type">授权类型</param>
        /// <returns></returns>
        public async Task RemoveAllAsync(string subjectId, string clientId, string type)
        {
            await _db.Deleteable<PersistedGrant>()
                      .Where(m => m.ClientId == clientId && m.SubjectId == subjectId && m.Type == type)
                      .ExecuteCommandAsync();
        }

        /// 移除指定的标识、客户端、类型等授权信息
        /// </summary>
        /// <returns></returns>

        public async Task RemoveAllAsync(PersistedGrantFilter filter)
        {
            await _db.Deleteable<PersistedGrant>()
               .Where(x => x.SubjectId == filter.SubjectId)
               .Where(x => x.SessionId == filter.SessionId)
               .Where(x => x.ClientId == filter.ClientId)
               .Where(x => x.Type == filter.Type)
               .ExecuteCommandAsync();
        }

        /// <summary>
        /// 移除指定KEY的授权信息
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task RemoveAsync(string key)
        {
            await _db.Deleteable<PersistedGrant>()
                      .Where(m => m.Key == key)
                      .ExecuteCommandAsync();
        }

        /// <summary>
        /// 存储授权信息
        /// </summary>
        /// <param name="grant">实体</param>
        /// <returns></returns>
        public async Task StoreAsync(IdentityServer4.Models.PersistedGrant grant)
        {
            //"insert into PersistedGrants([Key],ClientId,CreationTime,Data,Expiration,SubjectId,Type) values(@Key,@ClientId,@CreationTime,@Data,@Expiration,@SubjectId,@Type)";
            await _db.Insertable<PersistedGrant>(grant.ToEntity())
                      .ExecuteCommandAsync();
        }

        
    }
}
